import {
  type BoundingBox,
  GraphicObject,
  GraphicType,
  type Point,
  type ViewTransform,
} from '../GraphicObject';
import TransformManager from '../TransformManager';
import type { GraphicObjectData } from '../types';

export class Circle extends GraphicObject {
  public radius: number;
  static create: (
    radius: number,
    options?: {
      transform?: any;
      style?: any;
      layerId?: string;
    },
  ) => Circle;

  constructor(
    radius: number,
    transform = GraphicObject.defaultTransform(),
    style = GraphicObject.defaultStyle(),
    layerId = 'default',
  ) {
    super(GraphicType.CIRCLE, transform, style, layerId);
    this.radius = radius;
  }

  draw(ctx: CanvasRenderingContext2D, viewTransform: ViewTransform): void {
    ctx.save();

    // 应用视图变换
    ctx.translate(viewTransform.offset.x, viewTransform.offset.y);
    ctx.scale(viewTransform.scale, viewTransform.scale);
    ctx.rotate(viewTransform.rotation);

    // 应用对象变换
    ctx.translate(this.transform.position.x, this.transform.position.y);
    ctx.rotate(this.transform.rotation);
    ctx.scale(this.transform.scale.x, this.transform.scale.y);

    // 设置样式
    if (this.style.fillColor) {
      ctx.fillStyle = this.style.fillColor;
    }
    if (this.style.strokeColor) {
      ctx.strokeStyle = this.style.strokeColor;
    }
    if (this.style.strokeWidth) {
      ctx.lineWidth = this.style.strokeWidth / viewTransform.scale;
    }
    if (this.style.opacity) {
      ctx.globalAlpha = this.style.opacity;
    }
    if (this.style.lineDash) {
      ctx.setLineDash(this.style.lineDash);
    }

    // 绘制圆形
    ctx.beginPath();
    ctx.arc(0, 0, this.radius, 0, 2 * Math.PI);

    // 填充和描边
    if (this.style.fillColor) {
      ctx.fill();
    }
    if (this.style.strokeColor && this.style.strokeWidth) {
      ctx.stroke();
    }

    ctx.restore();
  }

  contains(point: Point): boolean {
    // 将世界坐标转换为对象局部坐标
    const localPoint = TransformManager.worldToLocal(point, this.transform);

    // 计算到圆心的距离
    const distance = Math.sqrt(localPoint.x ** 2 + localPoint.y ** 2);

    return distance <= this.radius;
  }

  getBoundingBox(): BoundingBox {
    const diameter = this.radius * 2;
    return {
      x: this.transform.position.x - this.radius,
      y: this.transform.position.y - this.radius,
      width: diameter * this.transform.scale.x,
      height: diameter * this.transform.scale.y,
    };
  }

  /**
   * 序列化对象数据
   */
  serialize(): GraphicObjectData {
    return {
      id: this.id,
      type: this.type,
      transform: { ...this.transform },
      style: { ...this.style },
      layerId: this.layerId,
      radius: this.radius,
    };
  }
}

// 静态创建方法
Circle.create = (
  radius: number,
  options?: {
    transform?: any;
    style?: any;
    layerId?: string;
  },
) => {
  return new Circle(
    radius,
    options?.transform,
    options?.style,
    options?.layerId,
  );
};
